package cn.csc.module.product.dal.mysql.stock;

import cn.csc.framework.common.pojo.PageResult;
import cn.csc.framework.mybatis.core.mapper.BaseMapperX;
import cn.csc.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.csc.framework.mybatis.core.query.LambdaUpdateWrapperX;
import cn.csc.module.product.controller.admin.stock.vo.SkuStockExportReqVO;
import cn.csc.module.product.controller.admin.stock.vo.SkuStockPageReqVO;
import cn.csc.module.product.dal.dataobject.stock.SkuStockDO;
import cn.csc.module.product.dal.dataobject.stocklock.SkuStockLockDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.math.BigInteger;
import java.util.List;

/**
 * 库存信息 Mapper
 *
 * @author liuchuang
 */
@Mapper
public interface SkuStockMapper extends BaseMapperX<SkuStockDO> {

    default PageResult<SkuStockDO> selectPage(SkuStockPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<SkuStockDO>()
                .eqIfPresent(SkuStockDO::getSkuId, reqVO.getSkuId())
                .eqIfPresent(SkuStockDO::getActualStock, reqVO.getActualStock())
                .eqIfPresent(SkuStockDO::getLockStock, reqVO.getLockStock())
                .eqIfPresent(SkuStockDO::getStock, reqVO.getStock())
                .betweenIfPresent(SkuStockDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(SkuStockDO::getId));
    }

    default List<SkuStockDO> selectList(SkuStockExportReqVO reqVO) {
        return selectList(new LambdaQueryWrapperX<SkuStockDO>()
                .eqIfPresent(SkuStockDO::getSkuId, reqVO.getSkuId())
                .eqIfPresent(SkuStockDO::getActualStock, reqVO.getActualStock())
                .eqIfPresent(SkuStockDO::getLockStock, reqVO.getLockStock())
                .eqIfPresent(SkuStockDO::getStock, reqVO.getStock())
                .betweenIfPresent(SkuStockDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(SkuStockDO::getId));
    }

    default SkuStockDO selectBySkuId(BigInteger skuId) {
        return selectOne(new LambdaQueryWrapperX<SkuStockDO>()
                .eqIfPresent(SkuStockDO::getSkuId, skuId));
    }

    /**
     * 通过修改商品修改库存
     *
     * @param skuId 商品id
     * @param count 数量
     * @return
     */
    default int updateStockNumber(@Param("skuId") BigInteger skuId, @Param("count") Integer count){
        LambdaUpdateWrapperX<SkuStockDO> updateWrapper = new LambdaUpdateWrapperX();
        updateWrapper.set(SkuStockDO::getActualStock,count);
        updateWrapper.set(SkuStockDO::getStock,count);
        updateWrapper.eq(SkuStockDO::getSkuId,skuId);
        return update(null,updateWrapper);
    }

    /**
     * 通过修改商品修改库存
     *
     * @param skuId 商品id
     * @param count 数量
     * @return
     */
    default int updateStockNumberByOrder(@Param("skuId") BigInteger skuId, @Param("count") Integer count){
        LambdaUpdateWrapperX<SkuStockDO> updateWrapper = new LambdaUpdateWrapperX();
        updateWrapper.decreField(SkuStockDO::getActualStock,count);
        updateWrapper.decreField(SkuStockDO::getStock,count);
        updateWrapper.eq(SkuStockDO::getSkuId,skuId);
        return update(null,updateWrapper);
    }

    /**
     * 通过订单减少库存
     *
     * @param skuId 商品id
     * @param count 数量
     * @return
     */
    default int reduceStockByOrder(@Param("skuId") BigInteger skuId, @Param("count") Integer count){
        LambdaUpdateWrapperX<SkuStockDO> updateWrapper = new LambdaUpdateWrapperX();
        updateWrapper.decreField(SkuStockDO::getStock,count);
        updateWrapper.increField(SkuStockDO::getLockStock,count);
        updateWrapper.eq(SkuStockDO::getSkuId,skuId);
        updateWrapper.ge(SkuStockDO::getStock,count);
        return update(null,updateWrapper);
    }

    /**
     * 通过订单添加库存
     *
     * @param skuWithStocks 库存信息
     */
    Integer addStockByOrder(@Param("skuWithStocks") List<SkuStockLockDO> skuWithStocks);

    /**
     * 通过订单减少实际库存
     *
     * @param skuWithStocks 库存信息
     */
    Integer reduceActualStockByOrder(@Param("skuWithStocks") List<SkuStockLockDO> skuWithStocks);

    /**
     * 通过已经取消的订单减少实际库存
     *
     * @param skuWithStocks 库存信息
     */
    Integer reduceActualStockByCancelOrder(@Param("skuWithStocks") List<SkuStockLockDO> skuWithStocks);



}
